#pragma once

#include <string>
#include <jsoncpp/json/json.h>

#include "Log.hpp"

static const std::string sep = "\r\n";

// 拼接报文
std::string Encode(const std::string &jsonstr)
{
    int len = jsonstr.size();                 // 报文长度
    std::string lenstr = std::to_string(len); // 制作报头
    return lenstr + sep + jsonstr + sep;
}

// 拆封报文
// 不能带const
// "le
// "len"
// "len"\r\n
// "len"\r\n"{json}"\r\n (]
// "len"\r\n"{j
// "len"\r\n"{json}"\r\n"len"\r\n"{
// "len"\r\n"{json}"\r\n
// "len"\r\n"{json}"\r\n"len"\r\n"{json}"\r\n"len"\r\n"{json}"\r\n"len"\r\n"{json}"\r
std::string Decode(std::string &packagestream)
{
    // int index = packagestreamqueue.find(sep);
    // if (index != std::string::npos)
    // {
    //     std::string lenstr = packagestreamqueue.substr(0, index);       // 报头
    //     int strlen = std::stoi(lenstr);                      // 根据报头得到报文长度
    //     int total = lenstr.size() + sep.size() * 2 + strlen; // 报文总长度
    //     if (packagestreamqueue.size() < total)
    //     {
    //         return std::string();
    //     }
    //     std::string result = packagestreamqueue.substr(index + sep.size(), total); // 左闭右开区间
    //     packagestreamqueue.erase(0, total);                          // 剪切该次报文
    //     return result;
    // }
    // return std::string();
    auto pos = packagestream.find(sep);
    if (pos == std::string::npos)
        return std::string();
    std::string lenstr = packagestream.substr(0, pos);
    for(auto&ch :lenstr)
    {
        if(!isdigit(ch))
        {
            LOG(FATAL, "head error!\n");
            exit(HEAD_ERR);
        }
    }
    int len = std::stoi(lenstr);
    // 计算一个完整的报文应该是多长？？
    int total = lenstr.size() + len + 2 * sep.size();
    if (packagestream.size() < total)
        return std::string();

    // 提取
    std::string jsonstr = packagestream.substr(pos + sep.size(), len);
    packagestream.erase(0, total);
    return jsonstr;
}
class Request
{
public:
    Request()
    {
    }
    Request(int x, int y, char oper)
        : _x(x),
          _y(y),
          _oper(oper)
    {
    }
    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        Json::FastWriter writer;
        *out = writer.write(root);

        return true;
    }
    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();

        return true;
    }
    void Print()
    {
        // LOG(INFO, "_x:%d\n", _x);
        // LOG(INFO, "_y:%d\n", _y);
        // LOG(INFO, "_oper:%c\n", _oper);
        std::cout <<"x:"<< _x << std::endl;
        std::cout <<"y:"<< _y << std::endl;
        std::cout <<"oper:"<< _oper << std::endl;
        std::cout << std::endl;
    }
    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }
    void SetValue(int x, int y, char oper)
    {
        _x = x;
        _y = y;
        _oper = oper;
    }

private:
    // 请求的结构
    int _x;
    int _y;
    char _oper; // + - * / % // x oper y
};
class Response
{
public:
    Response():_result(0),_code(0),_desc("seccess")
    {
    }
    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;
        Json::FastWriter writer;
        std::string s = writer.write(root);
        *out = s;
        return true;
    }
    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root); // 这是干嘛的啊？？？
        if(!res)
            return false;
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();

        return true;
    }
    void PrintResult()
    {
        // LOG(INFO, "result:%d,code:%d,desc:%s\n", _result, _code, _desc);
        std::cout << "result: " << _result << ", code: " << _code << ", desc: " << _desc << std::endl;
    }

public:
    // 响应的结构
    int _result;
    int _code; // 0: success, 1: div zero 2. 非法操作
    std::string _desc;
};

class Factory
{
public:
    static std::shared_ptr<Request> BuildRequestDefault()
    {
        return std::make_shared<Request>();
    }
    static std::shared_ptr<Response> BuildResponseDefault()
    {
        return std::make_shared<Response>();
    }
};